﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using IPC.Communication.Framework.BasicFramework;
using IPC.Communication.Framework.Core;
using IPC.Communication.Framework.Profinet.AllenBradley;
using IPC.Communication.Framework.Reflection;

namespace IPC.Communication.Framework.Profinet.Omron
{
    public class OmronCipNet : AllenBradleyNet
    {
        public OmronCipNet()
        {
        }

        public OmronCipNet(string ipAddress, int port = 44818)
            : base(ipAddress, port)
        {
        }

        [HslMqttApi("ReadByteArray", "")]
        public override OperateResult<byte[]> Read(string address, ushort length)
        {
            if (length > 1)
            {
                return Read(new string[1]
			{
				address
			}, new int[1]
			{
				1
			});
            }
            return Read(new string[1]
		{
			address
		}, new int[1]
		{
			length
		});
        }

        [HslMqttApi("ReadInt16Array", "")]
        public override OperateResult<short[]> ReadInt16(string address, ushort length)
        {
            if (length == 1)
            {
                return ByteTransformHelper.GetResultFromBytes(Read(address, 1), (byte[] m) => base.ByteTransform.TransInt16(m, 0, length));
            }
            int startIndex = HslHelper.ExtractStartIndex(ref address);
            return ByteTransformHelper.GetResultFromBytes(Read(address, 1), (byte[] m) => base.ByteTransform.TransInt16(m, (startIndex >= 0) ? (startIndex * 2) : 0, length));
        }

        [HslMqttApi("ReadUInt16Array", "")]
        public override OperateResult<ushort[]> ReadUInt16(string address, ushort length)
        {
            if (length == 1)
            {
                return ByteTransformHelper.GetResultFromBytes(Read(address, 1), (byte[] m) => base.ByteTransform.TransUInt16(m, 0, length));
            }
            int startIndex = HslHelper.ExtractStartIndex(ref address);
            return ByteTransformHelper.GetResultFromBytes(Read(address, 1), (byte[] m) => base.ByteTransform.TransUInt16(m, (startIndex >= 0) ? (startIndex * 2) : 0, length));
        }

        [HslMqttApi("ReadInt32Array", "")]
        public override OperateResult<int[]> ReadInt32(string address, ushort length)
        {
            if (length == 1)
            {
                return ByteTransformHelper.GetResultFromBytes(Read(address, 1), (byte[] m) => base.ByteTransform.TransInt32(m, 0, length));
            }
            int startIndex = HslHelper.ExtractStartIndex(ref address);
            return ByteTransformHelper.GetResultFromBytes(Read(address, 1), (byte[] m) => base.ByteTransform.TransInt32(m, (startIndex >= 0) ? (startIndex * 4) : 0, length));
        }

        [HslMqttApi("ReadUInt32Array", "")]
        public override OperateResult<uint[]> ReadUInt32(string address, ushort length)
        {
            if (length == 1)
            {
                return ByteTransformHelper.GetResultFromBytes(Read(address, 1), (byte[] m) => base.ByteTransform.TransUInt32(m, 0, length));
            }
            int startIndex = HslHelper.ExtractStartIndex(ref address);
            return ByteTransformHelper.GetResultFromBytes(Read(address, 1), (byte[] m) => base.ByteTransform.TransUInt32(m, (startIndex >= 0) ? (startIndex * 4) : 0, length));
        }

        [HslMqttApi("ReadFloatArray", "")]
        public override OperateResult<float[]> ReadFloat(string address, ushort length)
        {
            if (length == 1)
            {
                return ByteTransformHelper.GetResultFromBytes(Read(address, 1), (byte[] m) => base.ByteTransform.TransSingle(m, 0, length));
            }
            int startIndex = HslHelper.ExtractStartIndex(ref address);
            return ByteTransformHelper.GetResultFromBytes(Read(address, 1), (byte[] m) => base.ByteTransform.TransSingle(m, (startIndex >= 0) ? (startIndex * 4) : 0, length));
        }

        [HslMqttApi("ReadInt64Array", "")]
        public override OperateResult<long[]> ReadInt64(string address, ushort length)
        {
            if (length == 1)
            {
                return ByteTransformHelper.GetResultFromBytes(Read(address, 1), (byte[] m) => base.ByteTransform.TransInt64(m, 0, length));
            }
            int startIndex = HslHelper.ExtractStartIndex(ref address);
            return ByteTransformHelper.GetResultFromBytes(Read(address, 1), (byte[] m) => base.ByteTransform.TransInt64(m, (startIndex >= 0) ? (startIndex * 8) : 0, length));
        }

        [HslMqttApi("ReadUInt64Array", "")]
        public override OperateResult<ulong[]> ReadUInt64(string address, ushort length)
        {
            if (length == 1)
            {
                return ByteTransformHelper.GetResultFromBytes(Read(address, 1), (byte[] m) => base.ByteTransform.TransUInt64(m, 0, length));
            }
            int startIndex = HslHelper.ExtractStartIndex(ref address);
            return ByteTransformHelper.GetResultFromBytes(Read(address, 1), (byte[] m) => base.ByteTransform.TransUInt64(m, (startIndex >= 0) ? (startIndex * 8) : 0, length));
        }

        [HslMqttApi("ReadDoubleArray", "")]
        public override OperateResult<double[]> ReadDouble(string address, ushort length)
        {
            if (length == 1)
            {
                return ByteTransformHelper.GetResultFromBytes(Read(address, 1), (byte[] m) => base.ByteTransform.TransDouble(m, 0, length));
            }
            int startIndex = HslHelper.ExtractStartIndex(ref address);
            return ByteTransformHelper.GetResultFromBytes(Read(address, 1), (byte[] m) => base.ByteTransform.TransDouble(m, (startIndex >= 0) ? (startIndex * 8) : 0, length));
        }

        public override OperateResult<string> ReadString(string address, ushort length, Encoding encoding)
        {
            OperateResult<byte[]> operateResult = Read(address, length);
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<string>(operateResult);
            }
            int count = base.ByteTransform.TransUInt16(operateResult.Content, 0);
            return OperateResult.CreateSuccessResult(encoding.GetString(operateResult.Content, 2, count));
        }

        [HslMqttApi("WriteString", "")]
        public override OperateResult Write(string address, string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                value = string.Empty;
            }
            byte[] array = SoftBasic.SpliceArray<byte>(new byte[2], SoftBasic.ArrayExpandToLengthEven(Encoding.ASCII.GetBytes(value)));
            array[0] = BitConverter.GetBytes(array.Length - 2)[0];
            array[1] = BitConverter.GetBytes(array.Length - 2)[1];
            return base.WriteTag(address, 208, array);
        }

        [HslMqttApi("WriteByte", "")]
        public override OperateResult Write(string address, byte value)
        {
            return WriteTag(address, 209, new byte[2]
		{
			value,
			0
		});
        }

        public override OperateResult WriteTag(string address, ushort typeCode, byte[] value, int length = 1)
        {
            return base.WriteTag(address, typeCode, value);
        }

        //[AsyncStateMachine(typeof(<ReadAsync>d__15))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult<byte[]>> ReadAsync(string address, ushort length)
        //{
        //    <ReadAsync>d__15 stateMachine = new <ReadAsync>d__15();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<byte[]>>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.length = length;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<ReadInt16Async>d__16))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult<short[]>> ReadInt16Async(string address, ushort length)
        //{
        //    <ReadInt16Async>d__16 stateMachine = new <ReadInt16Async>d__16();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<short[]>>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.length = length;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<ReadUInt16Async>d__17))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult<ushort[]>> ReadUInt16Async(string address, ushort length)
        //{
        //    <ReadUInt16Async>d__17 stateMachine = new <ReadUInt16Async>d__17();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<ushort[]>>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.length = length;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<ReadInt32Async>d__18))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult<int[]>> ReadInt32Async(string address, ushort length)
        //{
        //    <ReadInt32Async>d__18 stateMachine = new <ReadInt32Async>d__18();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<int[]>>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.length = length;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<ReadUInt32Async>d__19))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult<uint[]>> ReadUInt32Async(string address, ushort length)
        //{
        //    <ReadUInt32Async>d__19 stateMachine = new <ReadUInt32Async>d__19();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<uint[]>>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.length = length;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<ReadFloatAsync>d__20))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult<float[]>> ReadFloatAsync(string address, ushort length)
        //{
        //    <ReadFloatAsync>d__20 stateMachine = new <ReadFloatAsync>d__20();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<float[]>>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.length = length;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<ReadInt64Async>d__21))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult<long[]>> ReadInt64Async(string address, ushort length)
        //{
        //    <ReadInt64Async>d__21 stateMachine = new <ReadInt64Async>d__21();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<long[]>>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.length = length;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<ReadUInt64Async>d__22))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult<ulong[]>> ReadUInt64Async(string address, ushort length)
        //{
        //    <ReadUInt64Async>d__22 stateMachine = new <ReadUInt64Async>d__22();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<ulong[]>>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.length = length;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<ReadDoubleAsync>d__23))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult<double[]>> ReadDoubleAsync(string address, ushort length)
        //{
        //    <ReadDoubleAsync>d__23 stateMachine = new <ReadDoubleAsync>d__23();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<double[]>>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.length = length;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<ReadStringAsync>d__24))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult<string>> ReadStringAsync(string address, ushort length, Encoding encoding)
        //{
        //    <ReadStringAsync>d__24 stateMachine = new <ReadStringAsync>d__24();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<string>>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.length = length;
        //    stateMachine.encoding = encoding;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<WriteAsync>d__25))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult> WriteAsync(string address, string value)
        //{
        //    <WriteAsync>d__25 stateMachine = new <WriteAsync>d__25();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.value = value;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<WriteAsync>d__26))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult> WriteAsync(string address, byte value)
        //{
        //    <WriteAsync>d__26 stateMachine = new <WriteAsync>d__26();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.value = value;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<WriteTagAsync>d__27))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult> WriteTagAsync(string address, ushort typeCode, byte[] value, int length = 1)
        //{
        //    <WriteTagAsync>d__27 stateMachine = new <WriteTagAsync>d__27();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.typeCode = typeCode;
        //    stateMachine.value = value;
        //    stateMachine.length = length;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        public override string ToString()
        {
            return String.Format("OmronCipNet[{0}:{1}]", IpAddress, Port);
        }
    }
}
